#include "rbtree.h"
#include <stdio.h>

void rb_get_size_(struct rb_node *node, int *size)
{
    if (!node || !size) {
        return ;
    } else if (node) {
        (*size) ++;
        rb_get_size_(node->rb_left, size);
        rb_get_size_(node->rb_right, size);
    }
    return ;
}

int rb_get_size(struct rb_root *root)
{
    int size = 0;
    if (root)
        rb_get_size_(root->rb_node, &size);
    return size;
}

struct rb_node *rb_preorder_show(struct rb_node *node, void (*show_func)(struct rb_node *node))
{
    if (node == 0)
        return 0;
    show_func(node);
    rb_preorder_show(node->rb_left, show_func);
    rb_preorder_show(node->rb_right, show_func);

    return node;
}

struct rb_node *rb_infixorder_show(struct rb_node *node, void (*show_func)(struct rb_node *node))
{
    if (node == 0)
        return 0;
    rb_infixorder_show(node->rb_left, show_func);
    show_func(node);
    rb_infixorder_show(node->rb_right, show_func);

    return node;
}

struct rb_node *rb_postorder_show(struct rb_node *node, void (*show_func)(struct rb_node *node))
{
    if (node == 0)
        return 0;
    rb_postorder_show(node->rb_left, show_func);
    rb_postorder_show(node->rb_right, show_func);
    show_func(node);

    return node;
}

struct rb_node *rb_preorder_get(struct rb_node *node, struct rb_node **to_nodes, int *size)
{
    if (!node || !to_nodes || !size) {
        return 0;
    } else if (node) {
        to_nodes[(*size) ++] = node;
        rb_preorder_get(node->rb_left, to_nodes, size);
        rb_preorder_get(node->rb_right, to_nodes, size);
    }
    return node;
}

struct rb_node *rb_infixorder_get(struct rb_node *node, struct rb_node **to_nodes, int *size)
{
   if (!node || !to_nodes || !size) {
        return 0;
    } else if (node) {
        rb_infixorder_get(node->rb_left, to_nodes, size);
        to_nodes[(*size) ++] = node;
        rb_infixorder_get(node->rb_right, to_nodes, size);
    }
    
    return node;  
}

struct rb_node *rb_postorder_get(struct rb_node *node, struct rb_node **to_nodes, int *size)
{
   if (!node || !to_nodes || !size) {
        return 0;
    } else if (node) {
        rb_postorder_get(node->rb_left, to_nodes, size);
        rb_postorder_get(node->rb_right, to_nodes, size);
        to_nodes[(*size) ++] = node;
    }  
    
    return node;
}
